import json
from io import StringIO, BytesIO
import segno
from django.http import HttpResponse, FileResponse
from django.shortcuts import render
from rest_framework import serializers
from rest_framework.views import APIView
from segno import DataOverflowError

from Apps.MakeQr.models import MakeQrStore
from Apps.MakeQr.ser import MakeQrStoreSer
from Apps.common.response import SuccessResponse, ErrorResponse
from Apps.util.request_util import setCreateUser


def make_and_open_Code(*args, **kwargs):
    qrcode = segno.make(**kwargs)
    return qrcode


class QrCode(APIView):
    authentication_classes = []

    def get(self, request, pk, *args, **kwargs):
        qrInstance = MakeQrStore.objects.get(id=pk)
        # {"content": "12121", "version": 1, "error": 'L', "boost_error": False, "micro": False}
        try:
            qrcode = make_and_open_Code(**qrInstance.make)
            out = BytesIO()
            qrcode.save(out, "png", **qrInstance.kw)
            out.seek(0)
            response = HttpResponse(content_type="image/png")
            response.write(out.read())
            response["Content-length"] = out.tell()
            return response

        except Exception as e:
            qrInstance.description = str(e)
            qrInstance.save()
            return ErrorResponse("生成失败☹️")


class PostQrCode(APIView):
    def post(self, request, *args, **kwargs):
        """
        make##########
        content:内容
        version:(Micro) QR Code 版本: 1 .. 40  或着 微小形版本 "M1", "M2", "M3", "M4"
        error：纠错等级：纠错能力(L,M,Q,H)
        boost_error
        mode:numeric 数字，
        ============    =======================
        Mode            (Micro) QR Code Version
        ============    =======================
        numeric         1 - 40, M1, M2, M3, M4
        alphanumeric    1 - 40,     M2, M3, M4
        byte            1 - 40,         M3, M4
        kanji           1 - 40,         M3, M4
        hanzi           1 - 40
        ============    =======================
        mark：二维码支持8种掩码方式，微二维码只支持4种。掩码是为了均衡暗模块和亮模块的比例，避免暗模块或亮模块并排或并列出现。

        save##########
        scale	该参数指示序列化的缩放因子。默认情况下，缩放因子为 1，这意味着暗/亮模块的大小被解释为特定输出格式中的一个单位(即，PNG 序列化方法为 1 像素，EPS 中为 1 点(1/72 英寸)) .一些序列化方法(如 PNG)仅接受整数值或将提供的缩放因子转换为整数。其他，如 SVG 和 EPS，接受浮点值并且不将其“降级”为整数。
        border	边距
        dark	前景色，None时前景透明
        light	背景色，None时前景透明
        alignment_dark	前景色对齐模式的颜色
        alignment_light	背景色对齐模式的颜色
        dark_module	某一个前景的点颜色
        data_dark	数据模块的前景颜色
        data_light	数据模块的背景颜色
        finder_dark	定位区暗模块的颜色
        finder_light	定位区亮模块的颜色
        format_dark	格式信息区的暗模块的颜色
        format_light	格式信息区的亮模块的颜色
        quiet_zone	静区(边框)的颜色
        separator	分隔区的颜色
        timing_dark	计时区的暗模块的颜色
        timing_light	计时区亮模块的颜色
        version_dark	版本信息区的暗模块的颜色(微二维码和低于版本7的二维码不携带任何版本信息)
        version_light	版本信息区亮模块的颜色

        """
        setCreateUser(request)
        serializer = MakeQrStoreSer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return SuccessResponse(serializer.data)


class QrCodeDownLoad(APIView):
    def get(self, request, *args, **kwargs):
        params = request.query_params
        qrInstance = MakeQrStore.objects.get(id=params["id"])

        try:
            qrcode = make_and_open_Code(**qrInstance.make)
            out = BytesIO()
            qrcode.save(out, params["fileType"], **qrInstance.kw)
            out.seek(0)
            response = FileResponse(out)
            response['Content-Type'] = 'application/octet-stream'
            response['Content-Disposition'] = f'attachment;filename="{params["id"]}.{params["fileType"]}"'
            # PayTemplate.jpg 返回文件的名称
            return response

        except Exception as e:
            qrInstance.description = str(e)
            qrInstance.save()
            return ErrorResponse("生成失败☹️")
